﻿using DFGK_WMS.Context;
using DFGK_WMS.IRepository;
using DFGK_WMS.IRepository.IService;
using DFGK_WMS.Model.Enum;
using DFGK_WMS.Model.Models;
using DFGK_WMS.WebAPI.Controllers.Result;
using DFGK_WMS.WebAPI.Filter;
using DFGK_WMS.WebAPI.Tools;
using Microsoft.AspNetCore.Mvc;
using NPOI.SS.Formula.Functions;
using NPOI.XWPF.UserModel;
using SqlSugar;
using System.Net.Mime;
using System.Security.Claims;

namespace DFGK_WMS.WebAPI.Controllers.RemoveInventory
{
    /// <summary>
    /// 移库管理
    /// </summary>
    [Route("api/[controller]")]
    [Head("移库管理")]
    [ApiController]
    public class RemoveInventoryController : BaseController
    {
        private readonly IRemoveInventoryService removeInvenService;
        private readonly ITTransferBinOrderRepository tTransferBinOrder;
        private readonly ISqlSugarClient _Client;

        public RemoveInventoryController(ISqlSugarClient client, DFGK_DB dFGK_DB, IRemoveInventoryService removeInventoryService, ITTransferBinOrderRepository tTransferBinOrder) : base(dFGK_DB)
        {
            _Client = client;
            removeInvenService = removeInventoryService;
            this.tTransferBinOrder = tTransferBinOrder;
        }

        /// <summary>
        /// 根据id查询移库单
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        [Route("GetRemoveInvenById/{id}")]
        public IActionResult GetRemoveInvenById(int id)
        {
            try
            {
                var result = _Client.Queryable<TTransferBinOrder>()
                  .AS("TTransferBinOrders")
                  .Single(it => it.Id == id);

                return new JsonResult(BaseResult.Result(result, "200"));
            }
            catch (Exception ex)
            {
                return new JsonResult(BaseResult.Result("500", ex.Message));
            }

        }


        /// <summary>
        /// 生成移库单号
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [Route("GetRemoveInvenOrder")]
        [Function("生成移库单号")]
        // [TypeFilter(typeof(CtmLogActionFilterAttribute))]
        public IActionResult CreateRemoveInven()
        {

            object transferBinOrder = new
            {
                OrderSn = base.CreateOrderID(Model.Enum.OperationEnum.Remove),
                Status = (int)EmBillStatus.Create,
                Proirity = 0,
                SourceType = 1
            };

            var result = BaseResult.Result(transferBinOrder, "200");
            return new JsonResult(result);
        }

        /// <summary>
        /// 显示查询分页移库单
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>

        [HttpGet]
        [Route("GetRemoveInven")]
        public IActionResult GetRemoveInven(string? numbering, int pageIndex = 1, int pageSize = 10)
        {
            var query = _Client.Queryable<TTransferBinOrder>().AS("TTransferBinOrders");

            if (string.IsNullOrEmpty(numbering))
            {
                var result = query.ToPageList(pageIndex, pageSize);
                int totalCount = result.Count();
                return new JsonResult(BaseResult.Result(result, "200", totalCount));
            }
            else
            {
                var result = query.Where(it => it.OrderSn.Contains(numbering)).ToPageList(pageIndex, pageSize);
                int totalCount = result.Count();
                return new JsonResult(BaseResult.Result(result, "200", totalCount));
            }
        }

        /// <summary>
        /// 根据id查询移库单明细
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        [Route("GetRemoveInvenOrderById/{id}")]
        public IActionResult GetRemoveInvenOrderById(int id)
        {

            var result = _Client.Queryable<TTransferBinOrderDetail>()
                .AS("TTransferBinOrderDetails")
                .Single(it => it.Id == id);

            return new JsonResult(BaseResult.Result(result, "200"));
        }
        /// <summary>
        /// 移库单删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpDelete]
        [Route("DelRemoveInven/{id}")]
        public IActionResult DelRemoveInven(int id)
        {
            try
            {
                // 查询移库单的状态
                var status = _Client.Queryable<TTransferBinOrder>().Where(t => t.Id == id).Select(t => t.Status).First();
                var a = _Client.Queryable<TTransferBinOrderDetail>().Where(t => t.OrderId == id);

                if (status == 3 || status == 4 || status == 5)
                {
                    return new JsonResult(BaseResult.Result(false, "403", "作业中、已完成不能删除"));
                }

                // 执行删除操作，具体的删除逻辑需要根据实际情况来实现
                var result = _Client.Deleteable<TTransferBinOrder>().In(id).ExecuteCommand();

                if (result > 0)
                {
                    return new JsonResult(BaseResult.Result(true, "200", "删除成功"));
                }
                else
                {
                    return new JsonResult(BaseResult.Result(false, "500", "删除失败"));
                }
            }
            catch (Exception ex)
            {
                // 如果发生异常，返回异常信息
                return new JsonResult(BaseResult.Result(false, "500", "删除失败：" + ex.Message));
            }
        }
        /// <summary>
        /// 创建移库单
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("InsertTransferBinOrder")]
        [Function("创建移库单")]
        public IActionResult InsertTransferBinOrder(TTransferBinOrder model)
        {
            bool result = false;
            _Client.Ado.BeginTran();
            //var dile = _Client.Queryable<TCompany>().First(t => t.Id == model.CompanyId).Name;
            try
            {
                //var currentUser = base.GetUserInfo();
                //transferBinOrder.CreateUserId = currentUser.Item1;
                //transferBinOrder.CreateUserName = currentUser.Item2;
                //transferBinOrder.CreateDate = DateTime.Now;
                string uname = HttpContext.User.FindFirstValue("UserName");
                string runame = HttpContext.User.FindFirstValue("RealName");
                int uid = Convert.ToInt32(HttpContext.User.FindFirstValue("Id"));
                string schedulingInfo = HttpContext.User.FindFirstValue("SchedulingInfo");
                string? ip = HttpContext.Connection.RemoteIpAddress?.ToString();
                TCompany company = new TCompany();
                //var aname = _Client.Queryable<TCompany>().First(t => t.Id == model.CompanyId).Name;
                model.CreateUserId = uid;
                model.CreateUserName = uname;
                model.CreateDate = DateTime.Now;
                model.Status = 0;
                model.SourceType = 1;
                TTransferBinOrderDetail transferobj = new TTransferBinOrderDetail();
                foreach (var item in model.OrderDetailList)
                {
                    var list = _Client.Queryable<TCell>().Where(x => x.Code == item.ToLocationCode).Select(x => x.Name).ToList();
                    if (list.Count <= 0)
                    {
                        return Ok(false);
                    }
                    item.ToLocationName = list.FirstOrDefault();
                    transferobj = item;
                }
                //if(transferobj!=null)
                //    model.OrderDetailList.Add(transferobj);
                //model.CompanyName = aname;
                //model.SchedulingInfo = schedulingInfo;
                var id = _Client.Insertable(model).ExecuteReturnIdentity();
                result = id > 0;
                if (!result)
                {
                    _Client.Ado.RollbackTran();
                    return Ok(false);
                }

                // 创建日志模型对象
                TLog logModel = new TLog();

                logModel.LogType = (int)EmDbLogType.Operate;
                logModel.ActionType = (int)EmLogAction.Create;
                logModel.RecordType = (int)EmFuncRecordType.MoveOrder;
                logModel.RecordId = id;
                logModel.Status = 0;
                logModel.CreateDate = model.CreateDate;
                logModel.RealName = runame;
                logModel.UserId = model.CreateUserId;
                logModel.UserName = model.CreateUserName;
                logModel.RealName = model.CreateUserName;
                logModel.ModuleName = "移库单";
                logModel.Ipaddress = ip;
                logModel.Description = model.CreateUserName + "创建了移库单" + model.OrderSn;

                // 调用InsertLog方法
                result = _Client.Insertable(logModel).ExecuteCommand() > 0;

                if (model.OrderDetailList != null && model.OrderDetailList.Count > 0)
                {
                    foreach (TTransferBinOrderDetail item in model.OrderDetailList)
                    {
                        item.OrderId = id;
                        item.OrderSn = model.OrderSn;
                        item.Status = 0;
                        item.CreateUserId = model.CreateUserId;
                        item.CreateUserName = model.CreateUserName;
                        item.CreateDate = model.CreateDate;
                        item.ModifyUserId = model.ModifyUserId;
                        item.ModifyUserName = model.ModifyUserName;
                        item.ModifyDate = model.ModifyDate;
                        result = result && _Client.Insertable(item).ExecuteCommand() > 0;
                    }
                }

                if (result)
                {
                    _Client.Ado.CommitTran();

                    return new JsonResult(BaseResult.Result("200", "添加成功"));
                }
                else
                {
                    _Client.Ado.RollbackTran();
                    return new JsonResult(BaseResult.Result("200", "添加失败"));
                }
            }
            catch (Exception ex)
            {
                _Client.Ado.RollbackTran();
                return new JsonResult(BaseResult.Result("500", "添加失败，程序异常：" + ex.Message));
            }

        }


        /// <summary>
        ///  创建移库单
        /// </summary>
        /// <param name="transferBinOrder"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("AddTransferBinOrder")]
        public IActionResult AddTransferBinOrder(TTransferBinOrder transferBinOrder)
        {

            try
            {
                var currentUser = base.GetUserInfo();
                transferBinOrder.CreateUserId = currentUser.Item1;
                transferBinOrder.CreateUserName = currentUser.Item2;
                transferBinOrder.CreateDate = DateTime.Now;

                _Client.Ado.BeginTran();

                int id = _Client.Insertable<TTransferBinOrder>(transferBinOrder).ExecuteReturnIdentity();
                bool result = id > 0;
                if (result)
                {
                    if (transferBinOrder.OrderDetailList != null && transferBinOrder.OrderDetailList?.Count != 0)
                    {
                        foreach (var item in transferBinOrder.OrderDetailList)
                        {
                            item.OrderId = id;
                        }

                        result = _Client.Insertable<TTransferBinOrderDetail>(transferBinOrder.OrderDetailList).ExecuteCommand() > 0;

                    }

                }

                if (result)
                {
                    _Client.Ado.CommitTran();

                    return new JsonResult(BaseResult.Result("200", "添加成功"));
                }
                else
                {
                    _Client.Ado.RollbackTran();
                    return new JsonResult(BaseResult.Result("200", "添加失败"));
                }
            }
            catch (Exception ex)
            {
                _Client.Ado.RollbackTran();
                return new JsonResult(BaseResult.Result("500", "添加失败，程序异常：" + ex.Message));
            }


        }

        /// <summary>
        /// 获取移库可用仓位
        /// </summary>
        /// <param name="locationId">仓位id</param>
        /// <param name="toLogicalPartCode">逻辑分区编码</param>
        /// <param name="isPriorityFilling">true 深货有位  false整列全空</param>
        /// <param name="filterType">1同物料同批次 2同物料不同批次 3不限物料不限批次</param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        [HttpGet]
        [Route("GetRemoveCell")]
        public IActionResult GetRemoveCell(int locationId, string? toLogicalPartCode, bool isPriorityFilling , int filterType = 1)
        {
            try
            {
                var cellList = removeInvenService.GetRmoveEnableCell(locationId, toLogicalPartCode, isPriorityFilling, filterType);
                return new JsonResult(BaseResult.Result(cellList, "200"));
            }
            catch (Exception ex)
            {
                return new JsonResult(BaseResult.Result("500", ex.Message));
            }

        }

        /// <summary>
        /// 修改移库单
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("UpdTransferBinOrder")]
        public IActionResult UpdTransferBinOrder(TTransferBinOrder model)
        {
            bool result = false;
            _Client.Ado.BeginTran();
            //var gs = _Client.Queryable<TCompany>().First(t => t.Id == model.CompanyId).Name;
            try
            {
                string uname = HttpContext.User.FindFirstValue("UserName");
                string runame = HttpContext.User.FindFirstValue("RealName");
                int uid = Convert.ToInt32(HttpContext.User.FindFirstValue("Id"));
                string? ip = HttpContext.Connection.RemoteIpAddress?.ToString();
                model.ModifyUserId = uid;
                model.ModifyUserName = uname;
                model.ModifyDate = DateTime.Now;
                //model.CompanyName = gs;
                var id = _Client.Updateable(model).ExecuteCommand();
                result = id > 0;
                if (!result)
                {
                    _Client.Ado.RollbackTran();
                    return Ok(false);
                }

                // 创建日志模型对象
                TLog logModel = new TLog();

                logModel.LogType = (int)EmDbLogType.Operate;
                logModel.ActionType = (int)EmLogAction.Create;
                logModel.RecordType = (int)EmFuncRecordType.MoveOrder;
                logModel.RecordId = id;
                logModel.Status = 1;
                logModel.CreateDate = model.ModifyDate;
                logModel.RealName = runame;
                logModel.UserId = model.ModifyUserId;
                logModel.UserName = model.ModifyUserName;
                logModel.ModuleName = "移库单";
                logModel.Ipaddress = ip;
                logModel.Description = model.CreateUserName + "修改了移库单" + model.OrderSn;

                // 调用InsertLog方法
                result = _Client.Updateable(logModel).ExecuteCommand() > 0;


                if (model.OrderDetailList != null && model.OrderDetailList.Count > 0)
                {
                    foreach (TTransferBinOrderDetail item in model.OrderDetailList)
                    {
                        var dile = _Client.Queryable<TTransferBinOrderDetail>().First(t => t.OrderId == model.Id);
                        item.Id = dile.Id;
                        item.OrderId = model.Id;
                        item.OrderSn = model.OrderSn;
                        item.CreateUserId = model.CreateUserId;
                        item.CreateUserName = model.CreateUserName;
                        item.CreateDate = model.CreateDate;
                        item.ModifyUserId = model.ModifyUserId;
                        item.ModifyUserName = model.ModifyUserName;
                        item.ModifyDate = model.ModifyDate;
                        result = _Client.Updateable(item).ExecuteCommand() > 0;
                    }
                }

                if (result == true)
                {
                    _Client.Ado.CommitTran();

                    return new JsonResult(BaseResult.Result("200", "修改成功", true));
                }
                else
                {
                    _Client.Ado.RollbackTran();
                    return new JsonResult(BaseResult.Result("500", "修改失败", false));
                }
            }
            catch (Exception ex)
            {
                _Client.Ado.RollbackTran();
                return new JsonResult(BaseResult.Result("500", "修改失败，程序异常：" + ex.Message));
            }
        }
        /// <summary>
        /// 修改移库单状态
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [Route("UpdTransferStatu")]
        public IActionResult UpdTransferStatu(int id)
        {
            try
            {
                _Client.Ado.BeginTran();
                var result = _Client.Queryable<TTransferBinOrder>().Single(it => it.Id == id);
                var aa = _Client.Queryable<TTransferBinOrderDetail>().Where(it => it.OrderSn == result.OrderSn).ToList();
                foreach (var item in aa)
                {

                    if (result.Status == 0)
                    {
                        result.Status = 1;
                        item.Status = 1;
                    }
                    else if (result.Status == 1)
                    {
                        result.Status = 2;
                        item.Status = 2;
                    }
                    else if (result.Status == 2)
                    {
                        result.Status = 3;
                        item.Status = 3;
                    }
                    else if (result.Status == 3)
                    {
                        return new JsonResult(BaseResult.Result("500", "状态修改失败，正在执行中", false));
                    }
                    // 更新状态
                    _Client.Updateable(result).ExecuteCommand();
                    _Client.Updateable(aa).ExecuteCommand();

                    // 提交事务
                    _Client.Ado.CommitTran();

                }
                return new JsonResult(BaseResult.Result("200", "状态修改成功", true));

            }

            catch (Exception ex)
            {
                // 发生异常时回滚事务
                _Client.Ado.RollbackTran();

                return new JsonResult(BaseResult.Result("500", "状态修改失败，程序异常：" + ex.Message));
            }
        }

        /// <summary>
        /// 执行移库
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("ActionTransfer")]
        public IActionResult ActionTransfer(int id)
        {
            try
            {
                // 根据传入的 id 获取移库单信息
                var transferBinOrder = _Client.Queryable<TTransferBinOrder>().First(t => t.Id == id);

                if (transferBinOrder != null)
                {
                    // 执行移库操作，根据具体业务逻辑进行处理


                    // 更新移库单状态为已执行（假设状态字段为 Status）
                    transferBinOrder.Status = 4;
                    _Client.Updateable(transferBinOrder).ExecuteCommand();

                    return Ok(true); // 返回执行结果，可以根据需要返回其他信息
                }
                else
                {
                    return new JsonResult(BaseResult.Result(false, "500", "移库失败"));
                }
            }
            catch (Exception ex)
            {
                // 异常处理，返回特定格式的错误信息
                return new JsonResult(BaseResult.Result("500", ex.Message));
            }
        }
        /// <summary>
        /// 导出
        /// </summary>
        /// <param name="startTime"></param>
        /// <param name="endTime"></param>
        /// <param name="companyId"></param>
        /// <param name="status"></param>
        /// <returns></returns>
        [HttpGet]
        [Route("ExportToExcel")]
        public FileContentResult ExportToExcel(string? ordersn, DateTime? startTime, DateTime? endTime, int? companyId, int? status)
        {
            var list = tTransferBinOrder.GetExcel(ordersn, startTime, endTime, companyId, status);
            Dictionary<string, string> keyValuePairs = new Dictionary<string, string>()
            {
                {"OrderSn","移库单编号" },
                {"CompanyName","公司名称" },
                {"Reason","调整原因" },
                {"CreateUserName","移货人" },
                {"CreateDate","开始时间" },
                {"ModifyDate","完成时间" },
                {"Status","单据状态" },
            };
            //直接匿名对象就好
            var exList = list.Select(s => new
            {
                s.OrderSn,
                s.CompanyName,
                s.Reason,
                s.CreateUserName,
                s.CreateDate,
                ModifyDate = s.Status == 4 ? s.ModifyDate : (DateTime?)null,
                Status = ExStatusMapper(s.Status),
            }).ToList();

            var fileBytes = Utils.ExportToExcel(exList, keyValuePairs);
            return File(fileBytes, MediaTypeNames.Application.Octet, "移库管理.xlsx");
        }
        //状态转换
        private string ExStatusMapper(int? status)
        {
            if (status == 0)
            {
                return "创建";
            }
            if (status == 1)
            {
                return "提交";
            }
            if (status == 2)
            {
                return "审核通过";
            }
            if (status == 3)
            {
                return "作业中";
            }
            if (status == 4)
            {
                return "已完成";
            }
            return "";
        }
    }
}
